package com.jzxiang.pickerview;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrHelper;
import ohos.agp.components.Component;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.service.WindowManager;
import ohos.app.Context;

import com.jzxiang.pickerview.config.PickerConfig;
import com.jzxiang.pickerview.data.Type;
import com.jzxiang.pickerview.data.WheelCalendar;
import com.jzxiang.pickerview.listener.OnDateSetListener;

import java.util.Calendar;

/**
 * TimePickerDialog
 *
 * @since 2021-07-16
 */
public class TimePickerDialog extends CommonDialog implements Component.ClickedListener {
    private Context mContex;
    PickerConfig mPickerConfig;
    private TimeWheel mTimeWheel;
    private long mCurrentMillSeconds;
    private Component component;
    private AnimatorProperty animOutBOTTOM;

    /**
     * TimePickerDialog
     *
     * @param context context
     * @param pickerConfig pickerConfig
     */
    public TimePickerDialog(Context context, PickerConfig pickerConfig) {
        super(context);
        this.mContex = context;
        mPickerConfig = pickerConfig;
        initialize();
    }

    private void initialize() {
        getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_NAVIGATION);
        setAutoClosable(false); // 不能点外面取消,也不能点back取消
        initView();
        setContentCustomComponent(component);
        setTransparent(true);
        setAlignment(LayoutAlignment.BOTTOM);
        setDialogListener(new DialogListener() {
            @Override
            public boolean isTouchOutside() {
                dismissComDialog();
                return true;
            }
        });
    }

    /**
     * showDialog
     */
    public void showDialog() {
        AnimatorProperty property = createAnimBottom();
        animOutBOTTOM = createAnimOutBottom();
        property.setTarget(component);
        animOutBOTTOM.setTarget(component);
        show();
        property.start();
    }

    private void dismissComDialog() {
        animOutBOTTOM.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {

            }

            @Override
            public void onStop(Animator animator) {

            }

            @Override
            public void onCancel(Animator animator) {

            }

            @Override
            public void onEnd(Animator animator) {
                hide();
            }

            @Override
            public void onPause(Animator animator) {

            }

            @Override
            public void onResume(Animator animator) {

            }
        }).start();
    }

    private Component initView() {
        LayoutScatter layoutScatter = LayoutScatter.getInstance(mContex);
        component = (Component) layoutScatter.parse(ResourceTable.Layout_timepicker_layout, null, false);
        Text cancel = (Text) component.findComponentById(ResourceTable.Id_tv_cancel);
        cancel.setClickedListener(this);
        Text sure = (Text) component.findComponentById(ResourceTable.Id_tv_sure);
        sure.setClickedListener(this);
        Text title = (Text) component.findComponentById(ResourceTable.Id_tv_title);
        Component toolbar = component.findComponentById(ResourceTable.Id_toolbar);
        title.setText(mPickerConfig.mTitleString);
        cancel.setText(mPickerConfig.mCancelString);
        sure.setText(mPickerConfig.mSureString);
        ShapeElement shapeElement = new ShapeElement();
        int red = (mPickerConfig.mThemeColor >> 16) & 0xFF;
        int green = (mPickerConfig.mThemeColor >> 8) & 0xFF;
        int blue = mPickerConfig.mThemeColor & 0xFF;
        shapeElement.setRgbColor(new RgbColor(red, green, blue));
        toolbar.setBackground(shapeElement);
        mTimeWheel = new TimeWheel(component, mPickerConfig);

        if (mPickerConfig.orientation == mPickerConfig.VERTICAL) {
            setOffset(0, 0);
            component.setPaddingBottom(AttrHelper.vp2px(40, component.getContext()));
        } else if (mPickerConfig.orientation == mPickerConfig.HORIZONTAL) {
            setOffset(-25, 0);
            component.setPaddingBottom(AttrHelper.vp2px(0, component.getContext()));
        }
        return component;
    }

    @Override
    public void onClick(Component component) {
        int id = component.getId();
        if (id == ResourceTable.Id_tv_cancel) {
            dismissComDialog();
        } else if (id == ResourceTable.Id_tv_sure) {
            sureClicked();
        }
    }

    /**
     * getCurrentMillSeconds
     *
     * @return long
     */
    public long getCurrentMillSeconds() {
        if (mCurrentMillSeconds == 0) {
            return System.currentTimeMillis();
        }
        return mCurrentMillSeconds;
    }

    void sureClicked() {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();

        calendar.set(Calendar.YEAR, mTimeWheel.getCurrentYear());
        calendar.set(Calendar.MONTH, mTimeWheel.getCurrentMonth() - 1);
        calendar.set(Calendar.DAY_OF_MONTH, mTimeWheel.getCurrentDay());
        if (mPickerConfig.mType != Type.YEAR_MONTH_DAY) {
            calendar.set(Calendar.HOUR_OF_DAY, mTimeWheel.getCurrentHour());
            calendar.set(Calendar.MINUTE, mTimeWheel.getCurrentMinute());
        }
        if (mPickerConfig.mType == Type.HOURS_MINS) {
            calendar.set(Calendar.MONTH, 0);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
        } else if (mPickerConfig.mType == Type.YEAR_MONTH) {
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
        }
        mCurrentMillSeconds = calendar.getTimeInMillis();
        if (mPickerConfig.mCallBack != null) {
            mPickerConfig.mCallBack.onDateSet(this, mCurrentMillSeconds);
        }
        dismissComDialog();
    }

    /**
     * Builder
     *
     * @since 2021-07-16
     */
    public static class Builder {
        PickerConfig mPickerConfig;

        /**
         * Builder
         */
        public Builder() {
            mPickerConfig = new PickerConfig();
        }

        /**
         * setType
         *
         * @param type type
         * @return Builder
         */
        public Builder setType(Type type) {
            mPickerConfig.mType = type;
            return this;
        }

        /**
         * setThemeColor
         *
         * @param color color
         * @return Builder
         */
        public Builder setThemeColor(int color) {
            mPickerConfig.mThemeColor = color;
            return this;
        }

        /**
         * setCancelStringId
         *
         * @param left left
         * @return Builder
         */
        public Builder setCancelStringId(String left) {
            mPickerConfig.mCancelString = left;
            return this;
        }

        /**
         * setSureStringId
         *
         * @param right right
         * @return Builder
         */
        public Builder setSureStringId(String right) {
            mPickerConfig.mSureString = right;
            return this;
        }

        /**
         * setTitleStringId
         *
         * @param title title
         * @return Builder
         */
        public Builder setTitleStringId(String title) {
            mPickerConfig.mTitleString = title;
            return this;
        }

        /**
         * setToolBarTextColor
         *
         * @param color color
         * @return Builder
         */
        public Builder setToolBarTextColor(int color) {
            mPickerConfig.mToolBarTVColor = color;
            return this;
        }

        /**
         * Builder
         *
         * @param color color
         * @return Builder
         */
        public Builder setWheelItemTextNormalColor(int color) {
            mPickerConfig.mWheelTVNormalColor = color;
            return this;
        }

        /**
         * Builder
         *
         * @param color color
         * @return Builder
         */
        public Builder setWheelItemTextSelectorColor(int color) {
            mPickerConfig.mWheelTVSelectorColor = color;
            return this;
        }

        /**
         * setWheelItemTextSize
         *
         * @param size size
         * @return Builder
         */
        public Builder setWheelItemTextSize(int size) {
            mPickerConfig.mWheelTVSize = size;
            return this;
        }

        /**
         * Builder
         *
         * @param cyclic cyclic
         * @return Builder
         */
        public Builder setCyclic(boolean cyclic) {
            mPickerConfig.cyclic = cyclic;
            return this;
        }

        /**
         * Builder
         *
         * @param millseconds millseconds
         * @return Builder
         */
        public Builder setMinMillseconds(long millseconds) {
            mPickerConfig.mMinCalendar = new WheelCalendar(millseconds);
            return this;
        }

        /**
         * Builder
         *
         * @param millseconds millseconds
         * @return Builder
         */
        public Builder setMaxMillseconds(long millseconds) {
            mPickerConfig.mMaxCalendar = new WheelCalendar(millseconds);
            return this;
        }

        /**
         * Builder
         *
         * @param millseconds millseconds
         * @return Builder
         */
        public Builder setCurrentMillseconds(long millseconds) {
            mPickerConfig.mCurrentCalendar = new WheelCalendar(millseconds);
            return this;
        }

        /**
         * Builder
         *
         * @param year year
         * @return Builder
         */
        public Builder setYearText(String year) {
            mPickerConfig.mYear = year;
            return this;
        }

        /**
         * Builder
         *
         * @param month month
         * @return Builder
         */
        public Builder setMonthText(String month) {
            mPickerConfig.mMonth = month;
            return this;
        }

        /**
         * Builder
         *
         * @param day day
         * @return Builder
         */
        public Builder setDayText(String day) {
            mPickerConfig.mDay = day;
            return this;
        }

        /**
         * Builder
         *
         * @param hour hour
         * @return Builder
         */
        public Builder setHourText(String hour) {
            mPickerConfig.mHour = hour;
            return this;
        }

        /**
         * Builder
         *
         * @param minute minute
         * @return Builder
         */
        public Builder setMinuteText(String minute) {
            mPickerConfig.mMinute = minute;
            return this;
        }

        /**
         * Builder
         *
         * @param listener listener
         * @return Builder
         */
        public Builder setCallBack(OnDateSetListener listener) {
            mPickerConfig.mCallBack = listener;
            return this;
        }

        /**
         * setOrientation
         *
         * @param orientation orientation
         * @return Builder
         */
        public Builder setOrientation(int orientation) {
            mPickerConfig.orientation = orientation;
            return this;
        }

        /**
         * TimePickerDialog
         *
         * @param context context
         * @return TimePickerDialog
         */
        public TimePickerDialog build(Context context) {
            return new TimePickerDialog(context, mPickerConfig);
        }

    }

    private AnimatorProperty createAnimBottom() {
        AnimatorProperty animator = new AnimatorProperty();
        animator.moveFromY(800).moveToY(0).alphaFrom(0).alpha(1).setDuration(300);
        return animator;
    }

    private AnimatorProperty createAnimOutBottom() {
        AnimatorProperty animator = new AnimatorProperty();
        animator.moveFromY(0).moveToY(800).alphaFrom(1).alpha(0).setDuration(300);
        return animator;
    }

}
